﻿@using System.Linq
@using System.Collections
@using Radzen
@using Microsoft.AspNetCore.Components.Forms
@typeparam TValue
@inherits FormComponent<TValue>

@if (Items != null)
{
    <CascadingValue Value=this>
        @Items
    </CascadingValue>
}
@if (Visible)
{
    <div @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
        @foreach (var item in allItems.Where(i => i.Visible))
        {
            <div class="rz-radio-btn" @onclick="@(args => SelectItem(item))" @attributes="item.Attributes" style="@item.Style">
                <div class="rz-radiobutton" @onkeypress="@(async args => { if (args.Code == "Space") { await SelectItem(item); } })" tabindex="@TabIndex">
                    <div class="rz-helper-hidden-accessible">
                        <input type="radio" disabled="@Disabled" name="@Name" value="@item.Value" tabindex="-1">
                    </div>

                    @if (IsSelected(item))
                    {
                        <div class="@($"rz-radiobutton-box rz-state-active{getDisabledState(item)}")">
                            <span class="rz-radiobutton-icon  rzi rzi-circle-on"></span>
                        </div>
                    }
                    else
                    {
                        <div class="@($"rz-radiobutton-box {getDisabledState(item)}")">
                            <span class="rz-radiobutton-icon "></span>
                        </div>
                    }
                </div>
                <label class="rz-radiobutton-label">@item.Text</label>
            </div>
        }
    </div>
}

@code {
    [Parameter]
    public string ValueProperty { get; set; }

    [Parameter]
    public string TextProperty { get; set; }

    IEnumerable<RadzenRadioButtonListItem<TValue>> allItems
    {
        get
        {
            return items.Concat((Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()).Select(i =>
            {
                var item = new RadzenRadioButtonListItem<TValue>();
                item.SetText((string)PropertyAccess.GetItemOrValueFromProperty(i, TextProperty));
                item.SetValue((TValue)PropertyAccess.GetItemOrValueFromProperty(i, ValueProperty));
                return item;
            }));
        }
    }

    IEnumerable _data = null;
    [Parameter]
    public virtual IEnumerable Data
    {
        get
        {
            return _data;
        }
        set
        {
            if (_data != value)
            {
                _data = value;
                StateHasChanged();
            }
        }
    }

    protected override string GetComponentCssClass()
    {
        var fieldCssClass = FieldIdentifier.FieldName != null ? EditContext?.FieldCssClass(FieldIdentifier) : "";

        return $"{(Orientation == Orientation.Horizontal ? "rz-radio-button-list-horizontal" : "rz-radio-button-list-vertical")} {fieldCssClass}";
    }

    [Parameter]
    public Orientation Orientation { get; set; } = Orientation.Horizontal;

    [Parameter]
    public RenderFragment Items { get; set; }

    List<RadzenRadioButtonListItem<TValue>> items = new List<RadzenRadioButtonListItem<TValue>>();

    public void AddItem(RadzenRadioButtonListItem<TValue> item)
    {
        if (items.IndexOf(item) == -1)
        {
            items.Add(item);
            StateHasChanged();
        }
    }

    public void RemoveItem(RadzenRadioButtonListItem<TValue> item)
    {
        if (items.Contains(item))
        {
            items.Remove(item);
            try
            { InvokeAsync(StateHasChanged); }
            catch { }
        }
    }

    protected bool IsSelected(RadzenRadioButtonListItem<TValue> item)
    {
        return object.Equals(Value, item.Value);
    }

    protected async System.Threading.Tasks.Task SelectItem(RadzenRadioButtonListItem<TValue> item)
    {
        if (Disabled || item.Disabled)
            return;

        Value = item.Value;

        await ValueChanged.InvokeAsync(Value);
        if (FieldIdentifier.FieldName != null)
        { EditContext?.NotifyFieldChanged(FieldIdentifier); }
        await Change.InvokeAsync(Value);

        StateHasChanged();
    }

    private string getDisabledState(RadzenRadioButtonListItem<TValue> item)
    {
        return Disabled || item.Disabled ? " rz-state-disabled" : "";
    }

    public void Refresh()
    {
        StateHasChanged();
    }
}